"""
XCQuant 应用程序主类

整合所有架构组件，实现系统的统一启动、配置和管理
"""

import asyncio
import signal
import sys
from typing import Dict, Any, Optional, List
from pathlib import Path
from datetime import datetime
from .unified_core import unified_logger, config_manager, event_bus
from .exceptions import XCQuantError
from .service_registry import service_registry
from .module_manager import module_manager
from .component_factory import component_factory
from .plugin_manager import plugin_manager
from .performance import performance_monitor


class XCQuantApplication:
    """XCQuant 应用程序主类"""
    
    def __init__(self, config_path: str = None, app_name: str = "XCQuant"):
        self.app_name = app_name
        self.config_path = config_path
        self._logger = unified_logger.get_logger('application')
        self._running = False
        self._shutdown_event = asyncio.Event()
        
        # 应用状态
        self._startup_tasks: List[callable] = []
        self._shutdown_tasks: List[callable] = []
        self._initialized = False
        
        # 注册信号处理器
        self._setup_signal_handlers()
    
    def _setup_signal_handlers(self) -> None:
        """设置信号处理器"""
        def signal_handler(signum, frame):
            self._logger.info(f"接收到信号 {signum}，开始关闭应用程序...")
            asyncio.create_task(self.shutdown())
        
        signal.signal(signal.SIGINT, signal_handler)
        signal.signal(signal.SIGTERM, signal_handler)
    
    async def initialize(self) -> None:
        """初始化应用程序"""
        try:
            self._logger.info(f"初始化 {self.app_name} 应用程序...")
            
            # 1. 加载配置
            await self._load_configuration()
            
            # 2. 初始化核心组件
            await self._initialize_core_components()
            
            # 3. 发现和加载模块
            await self._load_modules()
            
            # 4. 加载插件
            await self._load_plugins()
            
            # 5. 初始化服务
            await self._initialize_services()
            
            # 6. 启动组件
            await self._start_components()
            
            self._initialized = True
            self._logger.info(f"{self.app_name} 应用程序初始化完成")
            
            # 发布初始化完成事件
            await event_bus.publish('app.initialized', {
                'app_name': self.app_name,
                'timestamp': datetime.now()
            })
            
        except Exception as e:
            self._logger.error(f"应用程序初始化失败: {e}")
            raise XCQuantError(f"应用程序初始化失败: {e}")
    
    async def _load_configuration(self) -> None:
        """加载配置"""
        self._logger.info("加载配置...")
        
        # 加载默认配置文件
        if self.config_path:
            config_file = Path(self.config_path)
            if config_file.exists():
                if config_file.suffix.lower() in ['.yaml', '.yml']:
                    config_manager.load_config_from_file('app', str(config_file))
                elif config_file.suffix.lower() == '.json':
                    config_manager.load_config_from_file('app', str(config_file))
        
        # 设置应用程序配置
        app_config = config_manager.get_config('app', default={})
        if not app_config:
            # 设置默认应用配置
            default_config = {
                'name': self.app_name,
                'version': '1.0.0',
                'debug': False,
                'log_level': 'INFO',
                'max_workers': 4,
                'enable_monitoring': True,
                'enable_plugins': True
            }
            config_manager.update_config('app', default_config)
        
        # 设置日志级别
        log_level = config_manager.get_config('app', 'log_level', 'INFO')
        # Logger类没有set_level方法，跳过日志级别设置
    
    async def _initialize_core_components(self) -> None:
        """初始化核心组件"""
        self._logger.info("初始化核心组件...")
        
        # 初始化事件总线
        # 事件总线已经是单例，无需特殊初始化
        
        # 初始化性能监控器
        if config_manager.get_config('app', 'enable_monitoring', True):
            await performance_monitor.start_monitoring()
        
        # 注册核心服务 - 使用简单的字典存储而不是类型注册
        # service_registry.register_service('event_bus', event_bus)
        # service_registry.register_service('config_manager', config_manager)
        # service_registry.register_service('performance_monitor', performance_monitor)
        # service_registry.register_service('component_factory', component_factory)
        # service_registry.register_service('plugin_manager', plugin_manager)
        # service_registry.register_service('module_manager', module_manager)
    
    async def _load_modules(self) -> None:
        """加载模块"""
        self._logger.info("发现和加载模块...")
        
        try:
            # 发现模块
            modules = module_manager.discover_modules()
            self._logger.info(f"发现 {len(modules)} 个模块")
            
            # 加载模块
            for module_name in modules:
                try:
                    module_manager.load_module(module_name)
                    self._logger.debug(f"加载模块: {module_name}")
                except Exception as e:
                    self._logger.error(f"加载模块失败 {module_name}: {e}")
            
            # 初始化所有模块
            await module_manager.initialize_all_modules()
            
        except Exception as e:
            self._logger.error(f"模块加载失败: {e}")
    
    async def _load_plugins(self) -> None:
        """加载插件"""
        if not config_manager.get_config('app', 'enable_plugins', True):
            self._logger.info("插件功能已禁用")
            return
        
        self._logger.info("发现和加载插件...")
        
        try:
            # 发现插件
            plugins = plugin_manager.discover_plugins()
            self._logger.info(f"发现 {len(plugins)} 个插件")
            
            # 加载插件
            for plugin_name in plugins:
                try:
                    plugin_manager.load_plugin(plugin_name)
                    self._logger.debug(f"加载插件: {plugin_name}")
                except Exception as e:
                    self._logger.error(f"加载插件失败 {plugin_name}: {e}")
            
        except Exception as e:
            self._logger.error(f"插件加载失败: {e}")
    
    async def _initialize_services(self) -> None:
        """初始化服务"""
        self._logger.info("初始化服务...")
        
        try:
            # 初始化服务注册中心中的所有服务
            await service_registry.initialize_all()
            
        except Exception as e:
            self._logger.error(f"服务初始化失败: {e}")
    
    async def _start_components(self) -> None:
        """启动组件"""
        self._logger.info("启动组件...")
        
        try:
            # 启动所有组件
            await component_factory.start_all_components()
            
            # 启动所有插件
            plugin_manager.start_all_plugins()
            
        except Exception as e:
            self._logger.error(f"组件启动失败: {e}")
    
    async def run(self) -> None:
        """运行应用程序"""
        try:
            if not self._initialized:
                await self.initialize()
            
            self._running = True
            self._logger.info(f"{self.app_name} 应用程序启动完成")
            
            # 发布应用程序启动事件
            await event_bus.publish_async('app.started', {
                'app_name': self.app_name,
                'timestamp': performance_monitor.get_current_time()
            })
            
            # 执行启动任务
            for task in self._startup_tasks:
                try:
                    if asyncio.iscoroutinefunction(task):
                        await task()
                    else:
                        task()
                except Exception as e:
                    self._logger.error(f"启动任务执行失败: {e}")
            
            # 等待关闭信号
            await self._shutdown_event.wait()
            
        except Exception as e:
            self._logger.error(f"应用程序运行失败: {e}")
            raise
        finally:
            await self.shutdown()
    
    async def shutdown(self) -> None:
        """关闭应用程序"""
        if not self._running:
            return
        
        self._logger.info(f"关闭 {self.app_name} 应用程序...")
        self._running = False
        
        try:
            # 发布应用程序关闭事件
            await event_bus.publish_async('app.shutting_down', {
                'app_name': self.app_name,
                'timestamp': performance_monitor.get_current_time()
            })
            
            # 执行关闭任务
            for task in reversed(self._shutdown_tasks):
                try:
                    if asyncio.iscoroutinefunction(task):
                        await task()
                    else:
                        task()
                except Exception as e:
                    self._logger.error(f"关闭任务执行失败: {e}")
            
            # 停止组件
            await component_factory.stop_all_components()
            
            # 停止插件
            plugin_manager.stop_all_plugins()
            
            # 关闭服务
            await service_registry.shutdown_all_services()
            
            # 停止性能监控器
            performance_monitor.stop()
            
            self._logger.info(f"{self.app_name} 应用程序已关闭")
            
        except Exception as e:
            self._logger.error(f"应用程序关闭失败: {e}")
        finally:
            self._shutdown_event.set()
    
    def add_startup_task(self, task: callable) -> None:
        """
        添加启动任务
        
        Args:
            task: 启动任务函数
        """
        self._startup_tasks.append(task)
    
    def add_shutdown_task(self, task: callable) -> None:
        """
        添加关闭任务
        
        Args:
            task: 关闭任务函数
        """
        self._shutdown_tasks.append(task)
    
    def get_status(self) -> Dict[str, Any]:
        """获取应用程序状态"""
        return {
            'name': self.app_name,
            'running': self._running,
            'initialized': self._initialized,
            'config': config_manager.get_config('app'),
            'services': len(service_registry.list_services()),
            'modules': len(module_manager.list_modules()),
            'plugins': len(plugin_manager.list_plugins()),
            'components': len(component_factory.list_components()),
            'uptime': performance_monitor.get_uptime() if self._running else 0
        }
    
    def configure(self, config: Dict[str, Any]) -> None:
        """
        配置应用程序
        
        Args:
            config: 配置数据
        """
        config_manager.update_config('app', config)
        
        # 更新日志级别
        if 'log_level' in config:
            unified_logger.set_level(config['log_level'])
    
    @property
    def is_running(self) -> bool:
        """应用程序是否正在运行"""
        return self._running
    
    @property
    def is_initialized(self) -> bool:
        """应用程序是否已初始化"""
        return self._initialized


def create_app(config_path: str = None, app_name: str = "XCQuant") -> XCQuantApplication:
    """
    创建应用程序实例
    
    Args:
        config_path: 配置文件路径
        app_name: 应用程序名称
    """
    return XCQuantApplication(config_path, app_name)


async def run_app(app: XCQuantApplication) -> None:
    """
    运行应用程序
    
    Args:
        app: 应用程序实例
    """
    await app.run()


# 默认应用程序实例
default_app = None


def get_app() -> Optional[XCQuantApplication]:
    """获取默认应用程序实例"""
    return default_app


def set_default_app(app: XCQuantApplication) -> None:
    """设置默认应用程序实例"""
    global default_app
    default_app = app